package com.swj.common.core.handler;

import com.swj.common.core.exception.auth.AuthException;
import com.swj.common.core.utils.ResponseUtil;
import com.swj.common.core.model.web.RestResult;
import feign.RetryableException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;


/**
 * 全局异常处理类
 *
 * @author 10834
 *
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {



    /**
     * 参数校验异常
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Object handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        bindingResult.getFieldErrors().forEach((fieldError) -> {
            stringBuilder.append(fieldError.getDefaultMessage());
            stringBuilder.append(",");
        });
        return ResponseUtil.failWithError(
                "参数验证不通过",stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString());
    }

    /**
     * Assert类型的验证错误
     */
    @ExceptionHandler({NestedServletException.class})
    public Object orgJunitAssertExceptionHandler(Exception e) {
        e.printStackTrace();
        String errorMessage = e.getMessage().replace("Handler dispatch failed;nested exception is java.lang.AssertionError:", "")
                .replace("Handler dispatch failed;nested exception is org.junit.ComparisonFailure:", "");
        if (errorMessage.contains("expected ")) {
            errorMessage = errorMessage.trim().split("expected ")[0];
            return ResponseUtil.failWithError(errorMessage, "断言失败");
        }
        return ResponseUtil.failWithError("断言失败",errorMessage);
    }


    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Object httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        String errorMessage = e.getMessage();
        assert errorMessage != null;
        int al = errorMessage.indexOf("from String");
        int a2 = errorMessage.indexOf("\":not a valid representation");
        String errorMessageResult = "非法输入异常HttpMessageNotReadableException：" + errorMessage.substring(al + 13, a2);
        return ResponseUtil.failWithError("输入不合法",errorMessageResult);
    }

    /**
     * 认证模块异常
     */
    @ExceptionHandler(AuthException.class)
    public RestResult<?> handleServiceException(AuthException e) {
        log.error("认证异常AuthException：{}", e.getMessage());
        return ResponseUtil.failWithError("认证失败",e.getMessage());
    }

    /**
     * sql异常
     */
    @ExceptionHandler(BadSqlGrammarException.class)
    public RestResult<?> handleBadSqlGrammarException(BadSqlGrammarException e) {
        log.error("sql语法异常BadSqlGrammarException：{}", e.getMessage());
        return ResponseUtil.failWithError(e.getMessage(),"sql语法异常");
    }

    /**
     * Feign超时异常
     */
    @ExceptionHandler(RetryableException.class)
    public RestResult<?> handleBadSqlGrammarException(RetryableException e) {
        log.error("重试异常RetryableException：{}", e.getMessage());
        String msg = e.getMessage()
                .replace("Read timed out", "读取时超时--->")
                .replace("executing", "执行")
                .replace("GET","get请求")
                .replace("POST","post请求");
        return ResponseUtil.failWithError("",msg);
    }

    @ExceptionHandler(RuntimeException.class)
    public Object defaultExceptionHandler(RuntimeException e) {
        e.printStackTrace();
        log.error("♥♥♥全局捕获RuntimeException异常：{}", e.getMessage());
        return ResponseUtil.failWithError("处理失败",e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Object defaultExceptionHandler(Exception e) {
        e.printStackTrace();
        log.error("♥♥♥全局捕获Exception异常：{}", e.getMessage());
        return ResponseUtil.failWithError("处理失败",e.getMessage());
    }

}
